#include "Shm.hpp"  // 包含“共享内存管理类” 
#include "Fifo.hpp" // 包含“命名管道操作类” + “文件操作类”

int main()
{
    //第一步：初始化共享内存对象 ---> 以"创建者（CREATER）"身份创建全新共享内存
    Shm shm(PathName, ProjId, CREATER); // 构造函数内部会完成：生成IPC键、创建共享内存、将共享内存映射到当前进程虚拟地址空间

    /*---------------------------命名管道---------------------------*/
    //1.初始化命名管道对象 ---> 创建名为FILENAME、路径为PATH的命名管道文件
    NamedFifo fifo(PATH, FILENAME); 

    //2.初始化命名管道读端操作对象
    FileOperator readerfile(PATH, FILENAME);

    //3.以只读模式打开命名管道 ---> 若写端未打开，此调用会阻塞，直到写端打开后返回
    readerfile.OpenForRead();



    /*---------------------------共享内存---------------------------*/
   
    //说明：根据需要的进行 ---> 注释or打开
    //sleep(5);  // 延迟5秒
    //shm.GetStat(); // 查看共享内存属性 ---> 打印共享内存大小、对应的IPC键值等信息

    //第二步：获取共享内存映射到当前进程的虚拟地址起始指针，强转为char*（方便按字符串读写）
    char *mem = (char *)shm.GetPtr();

    /* 关键说明：
    *     1. 对共享内存的读写直接通过虚拟地址操作，无需调用read/write等系统调用
    *     2. 相比其他IPC机制（管道、消息队列），共享内存无内核态与用户态的数据拷贝，通信效率最高
    */

    //第三步：循环读取共享内存数据：直到管道写端关闭（Wait返回false）
    while (true)
    {
        //情况一：唤醒成功（读取到管道数据）---> 打印共享内存中的字符串（共享内存已被写端写入数据）
        if (readerfile.Wait_Read())
        {
            printf("%s\n", mem);
        }
        //情况二：唤醒失败 ---> 管道写端关闭（Wait返回false），退出循环
        else
        {
            break;
        }
    }

    /*--------------------------------------------------------------------------------------------------*/

    //4.关闭命名管道的文件描述符，释放管道相关资源
    readerfile.Close();

    std::cout << "server end normal!" << std::endl;
    return 0;
}